#ifndef EXCEPTIONS_HPP
#define EXCEPTIONS_HPP

#include <exception>
#include "Shared.hpp"

namespace red{
	/// \brief Simple class for exception handling
	class Exception : public std::exception{
	public:
		Exception(const std::string &pMsg="");

		virtual ~Exception() throw();

		/// \brief Returns the exception associated message
		virtual const char* what() const throw();

	protected:
		std::string mMessage;
	};


	/// \brief Basic Exception with line and file of error handling. Use the Preprocessor ASSERT function instead
	struct AssertException : public Exception{
		AssertException(const std::string &pFile, int pLine, const std::string &pMsg);
	};

	/// Ease of Use.  Usage : Assert(conditionThatMustBeTrue);
	#ifdef _DEBUG
	#			define Assert(condition) if(!(condition)) \
					throw AssertException(__FILE__, __LINE__, "Unmet condition :\n\n" #condition)
	#else
				inline void DoNothing(bool) {}
	#			define Assert(condition) DoNothing(!(condition))
	#endif


	/// \brief Exception when error in deletion and memory handling occurs, used in MemoryManager mainly
	struct BadDelete : public Exception{
		BadDelete(unsigned long pPtr, const std::string &pFile, int pLine, bool pNewArray);
	};


	/// \brief Exception when file loading fail
	struct LoadingFailed : public Exception{
		LoadingFailed(const std::string &pFile, const std::string &pMsg);
	};
}
#endif
